package com.gitee.openviducn.inspector.auth;

import com.gitee.openviducn.inspector.constant.AppConstant;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import javax.servlet.http.HttpServletRequest;
import java.util.List;
import java.util.Map;
import java.util.Objects;

/**
 * 简单实现权限认证
 * 参考[https://github.com/alibaba/Sentinel/]控制台项目
 */
@Component
@Primary
@ConditionalOnProperty(name = "auth.enabled", matchIfMissing = true)
public class SimpleWebAuthServiceImpl implements AuthService<HttpServletRequest> {

    @Value("#{'${auth.filter.exclude-usernames}'.split(',')}")
    private List<String> safeUsernames;

    @Override
    public AuthUser getAuthUser(HttpServletRequest request) {
        String token = request.getHeader(AppConstant.HEADER_TOKEN);
        if (StringUtils.isBlank(token)) {
            return null;
        }
        Map<String, String> claims = JwtUtil.getClaims(token);
        if (Objects.isNull(claims) || claims.isEmpty()) {
            return null;
        }
        String userId = claims.get(USER_ID);
        String username = claims.get(USERNAME);
        String role = claims.get(ROLE);
        SystemRole systemRole = SystemRole.valueOf(role);
        // 简单检查是否安全用户名
        if (!safeUsernames.contains(username)) {
            return null;
        }
        return new SimpleWebAuthServiceImpl.SimpleWebAuthUserImpl(Long.parseLong(userId), username, systemRole);
    }

    public static final class SimpleWebAuthUserImpl implements AuthUser {

        private Long id;
        private String username;
        private SystemRole role;

        public SimpleWebAuthUserImpl(Long id, String username, SystemRole role) {
            this.id = id;
            this.username = username;
            this.role = role;
        }

        @Override
        public boolean authTarget(String target, SystemRole[] systemRoles) {
            if (systemRoles.length > 0) {
                for (SystemRole requireRole : systemRoles) {
                    if (Objects.equals(requireRole, this.getRole())) {
                        return true;
                    }
                }
                return false;
            }
            return true;
        }

        @Override
        public Long getId() {
            return id;
        }

        @Override
        public String getUsername() {
            return username;
        }

        @Override
        public SystemRole getRole() {
            return role;
        }
    }
}
